/**
 * 
 */
package tk.sunlatus.project.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.support.ServletContextResource;

import tk.sunlatus.project.common.constants.SunlatusConstants;
import tk.sunlatus.project.config.domain.ConfigFile;
import tk.sunlatus.project.config.xml.ConfigParserDom4jImpl;

/**
 * @author sunlotus
 * 
 */
public abstract class ConfigurationHolder implements ServletContextAware {

    private static final Logger LOGGER = Logger.getLogger(ConfigurationHolder.class);

    // 保存不需要实时更新的配置
    private Map<String, Configuration> cfgNoRefresh = new HashMap<String, Configuration>();
    // 保存需要实时更新的配置
    private Map<String, Configuration> cfgRefreshOnUsered = new HashMap<String, Configuration>();
    // 保存需要通过定时任务更新的配置
    private Map<String, Configuration> cfgRefreshByTask = new HashMap<String, Configuration>();

    private Resource configFile = null;

    private Configuration rootConfig = null;

    private ServletContext servletContext;

    private Map<String, ConfigFile> configFiles = new HashMap<String, ConfigFile>();

    public Map<String, Configuration> getCfgNoRefresh() {
        return cfgNoRefresh;
    }

    public Map<String, Configuration> getCfgRefreshOnUsered() {
        return cfgRefreshOnUsered;
    }

    public Map<String, Configuration> getCfgRefreshByTask() {
        return cfgRefreshByTask;
    }

    public void load() {

        XMLConfiguration config = new XMLConfiguration();
        ConfigParserDom4jImpl impl = new ConfigParserDom4jImpl();
        try {
            config.load(configFile.getURL());
            impl.parseDom(configFile.getFile());
            List<ConfigFile> files = impl.getConfigFileList();
            LOGGER.debug(files);
            init(files);
            rootConfig = config;
            // TODO 初始化

        } catch (ConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void init(List<ConfigFile> files) {

        Resource resource = null;
        Configuration cfg = null;
        for (ConfigFile file : files) {
            getConfigFiles().put(file.getKey(), file);
            resource = new ServletContextResource(this.servletContext, file.getPath());
            try {
                if (file.getType().equals(ConfigFile.Type.XML)) {
                    cfg = new XMLConfiguration(resource.getFile());
                } else if (file.getType().equals(ConfigFile.Type.PROPERTIES)) {
                    cfg = new PropertiesConfiguration(resource.getFile());
                } else {
                    continue;
                }

                saveByRefreshType(file, cfg);

            } catch (ConfigurationException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    private void saveByRefreshType(ConfigFile file, Configuration config) {
        // TODO Auto-generated method stub
        if (ConfigFile.RefreshType.REFRESH_NO.equals(file.getRefresh())) {
            this.cfgNoRefresh.put(file.getKey(), config);
        } else if (ConfigFile.RefreshType.RERESH_REAL_TIME.equals(file.getRefresh())) {
            this.cfgRefreshOnUsered.put(file.getKey(), config);
        } else if (ConfigFile.RefreshType.REFRESH_BY_TASK.equals(file.getRefresh())) {
            this.cfgRefreshByTask.put(file.getKey(), config);
        } else {
            // TODO 记录日志：不支持的加载类型
        }
    }

    public boolean isTest() {
        boolean result = false;
        if (rootConfig != null) {
            result = rootConfig.getBoolean(SunlatusConstants.SysConstant.isTestKey, false);
        }
        if (result) {
            // 记录日志：运行环境为测试环境
            LOGGER.debug("run mode is test");
        }
        return result;
    }

    public void setConfigFile(Resource configFile) {
        this.configFile = configFile;
    }

    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    ServletContext getServletContext() {
        return servletContext;
    }

    public Map<String, ConfigFile> getConfigFiles() {
        return configFiles;
    }
}
